﻿using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Sgr.Application;
using Sgr.Application.Commands;
using Sgr.Generator;
using Sgr.Identity;
using Sgr.Identity.Services;
using Sgr.Indentity.Application.ViewModels;
using Sgr.Security.VerifyCode;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Sgr.Indentity.Application.Commands
{
    /// <summary>
    /// 验证码登录命令处理器
    /// </summary>
    public class VerifyCodeLoginCommandHandle :
        LoginCommandHandleBase,
        IRequestHandler<VerifyCodeLoginCommand, CommandResult<TokenViewModel>>
    {
        private readonly IVerifyCodeService _verifyCodeService;

        public VerifyCodeLoginCommandHandle(
            IAccountAuthService accountService,
            IHttpContextAccessor httpContextAccessor,
            ISignatureChecker signatureChecker,
            IStringIdGenerator stringIdGenerator,
            IVerifyCodeService verifyCodeService,
            IOptions<IdentityOptions> options,
            ILogger<UserLoginCommandHandle> logger)
            : base(accountService, httpContextAccessor, signatureChecker, stringIdGenerator, options, logger)
        {
            _verifyCodeService = verifyCodeService ?? throw new ArgumentNullException(nameof(verifyCodeService));
        }

        /// <summary>
        /// 处理验证码登录请求
        /// </summary>
        public async Task<CommandResult<TokenViewModel>> Handle(VerifyCodeLoginCommand request, CancellationToken cancellationToken)
        {
            // 参数验证
            if (!ValidateRequest(request))
            {
                return CommandResult.Invalid<TokenViewModel>("请求参数无效");
            }

            // 验证验证码
            bool isValid = await _verifyCodeService.VerifyAsync(
                request.ReceiverType,
                request.Receiver,
                request.Purpose,
                request.VerificationCode,
                false,
                cancellationToken);

            if (!isValid)
                return CommandResult.Invalid<TokenViewModel>("验证码无效或已过期");

            // 根据接收类型和接收地址查找用户并登录
            var accountResult = await _accountService.ValidateAccountAsync(
                request.ReceiverType,
                request.Receiver,
                cancellationToken);

            AccountLoginWay accountLoginWay = request.ReceiverType == ReceiverType.Phone ? AccountLoginWay.PhoneVerification : AccountLoginWay.EmailVerification;
            // 处理登录结果
            return await ProcessLoginResultAsync(
                accountResult,
                request.Receiver,
                accountLoginWay,
                cancellationToken);
        }

        /// <summary>
        /// 验证请求参数
        /// </summary>
        private bool ValidateRequest(VerifyCodeLoginCommand request)
        {
            // 基本参数验证
            if (string.IsNullOrWhiteSpace(request.VerificationCode) ||
                string.IsNullOrWhiteSpace(request.Receiver) ||
                string.IsNullOrWhiteSpace(request.Purpose))
            {
                return false;
            }

            // 签名验证
            if (!ValidateSignature(
                request.Signature,
                request.Timestamp,
                request.Nonce,
                $"{request.Receiver}-{request.VerificationCode}",
                request.Receiver,
                request.Receiver))
            {
                return false;
            }

            // 图像验证码验证
            if (!ValidateImageVerificationCode(
                request.ImageVerificationCode,
                request.ImageVerificationHash,
                request.Receiver))
            {
                return false;
            }

            return true;
        }
    }
}